using Headsight.BPMN2WF.BPMN.Schemas;
using Headsight.BPMN2WF.Testing.TestObjCtors;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;

namespace Headsight.BPMN2WF.Testing.TestObjCtorsTest
{
    [TestClass]
    public class tDefinitionsCtorTest
    {
        private tDefinitionsCtor _sut;
        private tRootElement _tRootElem1;
        private tRootElement _tRootElem2;

        [TestInitialize]
        public void SetUp()
        {
            _sut = new tDefinitionsCtor();

            _tRootElem1 = new tRootElementCtor().Create();
            _tRootElem2 = new tRootElementCtor().Create();
        }

        [TestMethod]
        public void Create()
        {
            var result = _sut.Create();

            Assert.IsNotNull(result);
        }

        [TestMethod]
        public void With_tRootElement_is_chaining()
        {
            Assert.AreSame(_sut, _sut.With(_tRootElem1));
        }

        [TestMethod]
        public void With_tRootElement_Create()
        {
            var actual = _sut.With(_tRootElem1).With(_tRootElem2, _tRootElem1).Create();

            Assert.IsNotNull(actual.Items);
            Assert.AreEqual(3, actual.Items.Length);
            Assert.AreSame(_tRootElem1, actual.Items[0]);
        }

        [TestMethod]
        public void WithDiagramElement_is_chaining()
        {
            Assert.AreSame(_sut, _sut.WithDiagramElement(new BPMNShapeCtor().Create()));
        }

        [TestMethod]
        public void WithDiagramElement_Create()
        {
            var diagEl1 = new BPMNShapeCtor().Create();
            var diagEl2 = new BPMNShapeCtor().Create();

            var actual = _sut.WithDiagramElement(diagEl1).WithDiagramElement(diagEl2, diagEl1).Create();

            Assert.IsNotNull(actual.BPMNDiagram);
            Assert.AreEqual(1, actual.BPMNDiagram.Length);
            Assert.IsNotNull(actual.BPMNDiagram[0]);
            Assert.IsNotNull(actual.BPMNDiagram[0].BPMNPlane);
            Assert.IsNotNull(actual.BPMNDiagram[0].BPMNPlane.DiagramElements);
            Assert.AreEqual(3, actual.BPMNDiagram[0].BPMNPlane.DiagramElements.Length);
            
            Assert.AreSame(diagEl1, actual.BPMNDiagram[0].BPMNPlane.DiagramElements[0]);
            Assert.AreSame(diagEl2, actual.BPMNDiagram[0].BPMNPlane.DiagramElements[1]);
            Assert.AreSame(diagEl1, actual.BPMNDiagram[0].BPMNPlane.DiagramElements[2]);
        }

        [TestMethod]
        public void With_tRootElement_ITestObjectCtortRootElement_is_chaining()
        {
            var tRootElementCtor = MockRepository.GenerateStub<ITestObjCtor<tRootElement>>();
            // Create() shouldn't be called not until _sut.Create()...
            tRootElementCtor.Expect(x => x.Create()).Throw(new AssertFailedException());

            Assert.AreSame(_sut, _sut.With(tRootElementCtor));
        }

        [TestMethod]
        public void With_tRootElement_ITestObjectCtortRootElement_Create()
        {
            var tRootElementCtor = MockRepository.GenerateStub<ITestObjCtor<tRootElement>>();
            tRootElementCtor.Expect(x => x.Create()).Return(_tRootElem1);

            var actual = _sut.With(tRootElementCtor).Create();

            Assert.AreSame(_tRootElem1, actual.Items[0]);
        }
    }
}